package com.lglbc.day8;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @Description TODO
 * @Author 乐哥聊编程
 * @Date 2022/12/3 12:55
 */
@Slf4j
public class NettyClient {
    private Bootstrap bootstrap = null;
    private int failedCount = 0;

    public void initClient() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
        //设置相关参数
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new NettyClientHandler(NettyClient.this)); //加入自己的处理器
                    }
                });
        connect();
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyClient().initClient();
    }

    public void connect() throws InterruptedException {
        ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9999);
        channelFuture.addListener((ChannelFutureListener) future -> {
            if (!future.isSuccess()) {
                final EventLoop loop = channelFuture.channel().eventLoop();
                loop.schedule(() -> {
                    log.error("我与服务端失去了连接，我正在进行重连...");
                    try {
                        connect();
                        failedCount++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }, 3L, TimeUnit.SECONDS);
            } else {
                System.err.println("服务端连接成功...");
            }
        });
        //给关闭通道进行监听
        channelFuture.channel().closeFuture().sync();
    }
}

@Slf4j
class NettyClientHandler extends ChannelInboundHandlerAdapter {
    private NettyClient nettyClient;
    public NettyClientHandler(NettyClient nettyClient) {
        this.nettyClient = nettyClient;
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        try {
            ctx.pipeline().remove(this);
            ctx.channel().close();
            nettyClient.connect();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf byteBuf = (ByteBuf) msg;
        log.info("收到服务端消息:{}", byteBuf.toString(CharsetUtil.UTF_8));
    }
}
